package vn.smartoffice.promail.controller.mailCalendar;

import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;

import org.zkoss.calendar.Calendars;
import org.zkoss.calendar.api.CalendarEvent;
import org.zkoss.calendar.event.CalendarsEvent;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zkmax.ui.select.annotation.Subscribe;
import org.zkoss.zkplus.spring.DelegatingVariableResolver;
import org.zkoss.zul.Textbox;

import vn.smartoffice.auth.UserService;
import vn.smartoffice.promail.entity.MailCalendar;
import vn.smartoffice.promail.services.MailCalendarService;

@VariableResolver(DelegatingVariableResolver.class)
public class CalendarController extends SelectorComposer<Component> {

	private static final long serialVersionUID = 1L;

	@WireVariable
	MailCalendarService mailCalendarService;
	@WireVariable
	UserService userService;

	@Wire
	private Calendars calendars;
	@Wire
	private Textbox filter;

	private MailCalendarModel calendarModel;

	// the in editing calendar ui event
	private CalendarsEvent calendarsEvent = null;

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		List<CalendarEvent> demoCalendarEvents = mailCalendarService.findByUserId(userService.getCurrentUserId());
		calendarModel = new MailCalendarModel(demoCalendarEvents);
		calendars.setModel(this.calendarModel);
	}

	// control the calendar position
	@Listen("onClick = #today")
	public void gotoToday() {
		TimeZone timeZone = calendars.getDefaultTimeZone();
		calendars.setCurrentDate(Calendar.getInstance(timeZone).getTime());
	}

	@Listen("onClick = #next")
	public void gotoNext() {
		calendars.nextPage();
	}

	@Listen("onClick = #prev")
	public void gotoPrev() {
		calendars.previousPage();
	}

	// control page display
	@Listen("onClick = #pageDay")
	public void changeToDay() {
		calendars.setMold("default");
		calendars.setDays(1);
	}

	@Listen("onClick = #pageWeek")
	public void changeToWeek() {
		calendars.setMold("default");
		calendars.setDays(7);
	}

	@Listen("onClick = #pageMonth")
	public void changeToYear() {
		calendars.setMold("month");
	}

	// control the filter
	@Listen("onClick = #applyFilter")
	public void applyFilter() {
		calendarModel.setFilterText(filter.getValue());
		calendars.setModel(calendarModel);
	}

	@Listen("onClick = #resetFilter")
	public void resetFilter() {
		filter.setText("");
		calendarModel.setFilterText("");
		calendars.setModel(calendarModel);
	}

	// listen to the calendar-create and edit of a event data
	@Listen("onEventCreate = #calendars; onEventEdit = #calendars")
	public void createEvent(CalendarsEvent event) {
		calendarsEvent = event;

		// to display a shadow when editing
		calendarsEvent.stopClearGhost();

		MailCalendar data = (MailCalendar) event.getCalendarEvent();

		if (data == null) {
			data = new MailCalendar();
			data.setHeaderColor("#3366ff");
			data.setContentColor("#6699ff");
			data.setBeginDate(event.getBeginDate());
			data.setEndDate(event.getEndDate());
		} else {
			data = (MailCalendar) event.getCalendarEvent();
		}
		// notify the editor
		QueueUtil.lookupQueue().publish(new QueueMessage(QueueMessage.Type.EDIT, data));
	}

	// listen to the calendar-update of event data, usually send when user drag
	// the event data
	@Listen("onEventUpdate = #calendars")
	public void updateEvent(CalendarsEvent event) {
		MailCalendar data = (MailCalendar) event.getCalendarEvent();
		data.setBeginDate(event.getBeginDate());
		data.setEndDate(event.getEndDate());
		calendarModel.update(data);
		mailCalendarService.update(data);
	}

	// listen to queue message from other controller
	@Subscribe(value = QueueUtil.QUEUE_NAME)
	public void handleQueueMessage(QueueMessage message) {
		switch (message.getType()) {
		case DELETE:
			calendarModel.remove((MailCalendar) message.getData());
			mailCalendarService.deleteById(((MailCalendar) message.getData()).getId());
			// clear the shadow of the event after editing
			calendarsEvent.clearGhost();
			calendarsEvent = null;
			break;
		case OK:

			if (calendarModel.indexOf((MailCalendar) message.getData()) >= 0) {
				calendarModel.update((MailCalendar) message.getData());
				mailCalendarService.update((MailCalendar) message.getData());
			} else {
				MailCalendar data = (MailCalendar) message.getData();
				data.setUser(userService.getCurrentUser()); 
				calendarModel.add((MailCalendar) message.getData());
				mailCalendarService.save(data);
			}
		case CANCEL:
			// clear the shadow of the event after editing
			calendarsEvent.clearGhost();
			calendarsEvent = null;
			break;
		}
	}

	public boolean getLocked(int index) {
		if (index == 0) {
			return false;
		} else {
			return true;
		}
	}
}
